package cn.com.idmy.cloud.util;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.lang.tuple.Pair;
import org.dromara.hutool.core.text.split.SplitUtil;
import org.jetbrains.annotations.NotNull;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;

import static org.dromara.hutool.core.text.placeholder.StrFormatter.format;


@Slf4j
public class LealoneUtil {
    static String lastJdbcUrl;
    static ClassLoader classLoader = LealoneUtil.class.getClassLoader();

    @NotNull
    public static String run(@NotNull String db) {
        runSql("jdbc:lealone:embed:lealone", format("create database if not exists {} parameters(database_to_upper=false)", db));
        lastJdbcUrl = format("jdbc:lealone:embed:{}?trace_level_system_out=1&network_timeout=2147483647", db);
        runTable(lastJdbcUrl);
        runInit(lastJdbcUrl);
        return lastJdbcUrl;
    }

    @SneakyThrows
    static void runTable(@NotNull String jdbcUrl) {
        var filenames = IoUtil.readUtf8Lines(classLoader.getResourceAsStream("sql/tables"), new ArrayList<>());
        for (var filename : filenames) {
            String sql = IoUtil.readUtf8(classLoader.getResourceAsStream("sql/table/" + filename));
            runSql(jdbcUrl, sql);
        }
    }

    static void runInit(@NotNull String jdbcUrl) {
        var filenames = IoUtil.readUtf8Lines(classLoader.getResourceAsStream("sql/inits"), new ArrayList<>());
        for (var filename : filenames) {
            var init = IoUtil.readUtf8(classLoader.getResourceAsStream("sql/init/" + filename));
            var sqlLs = SplitUtil.split(init, ";");
            for (String sql : sqlLs) {
                try {
                    runSql(jdbcUrl, sql);
                } catch (Exception ignored) {
                }
            }
        }
    }

    static void runSql(@NotNull String jdbcUrl, @NotNull String sql) {
        Connection conn = null;
        Statement st = null;
        try {
            conn = DriverManager.getConnection(jdbcUrl);
            st = conn.createStatement();
            st.executeUpdate(sql);
            log.debug("execute sql: " + sql);
        } catch (Exception e) {
            log.warn("sql错误：{}", e.getMessage());
        } finally {
            IoUtil.closeQuietly(st, conn);
        }
    }

    static void runScript(@NotNull String jdbcUrl, @NotNull String path) {
        runSql(jdbcUrl, "runscript from '" + path + "'");
    }

    @NotNull
    public static Pair<String, String> runBackup() {
        var filename = DateUtil.format(new Date(), "yyyy-MM-dd-HH") + ".zip";
        var path = format("{}/{}/{}", System.getProperty("user.dir"), "backup", filename);
        runSql(lastJdbcUrl, format("backup to '{}'", path));
        return new Pair<>(filename, path);
    }
}
